//
// RS Game Framework
// Copyright © 2009 Jedd Haberstro
// jhaberstro@gmail.com
// 
// $Id:
//

#ifndef RS_META_METAFACILITIES_HPP
#define RS_META_METAFACILITIES_HPP

namespace rs
{
    namespace meta
    {
        namespace Internal
        {
            template< int > struct CompileTimeError;
            template < > struct CompileTimeError< true > { };
        }

#       define RS_ALT_STATIC_ASSERT(expression) \
            typedef char RsStaticAssert[(expression) ? 1 : -1];

#       define RS_STATIC_ASSERT(expression, message) \
            rs::meta::Internal::CompileTimeError< ((expression) != 0) > ERROR_##message;

        
        struct NullType { };
        
        template< bool value >
        struct BooleanType
        {
            static bool const Value = value;
            typedef BooleanType< value > ThisType;
            typedef bool ValueType;
            operator bool() const { return value; }
        };
        typedef BooleanType< false > FalseType;
        typedef BooleanType< true > TrueType;
        
        //////////////////////////////
        // TypeList & TypeValueList //
        //////////////////////////////
        //struct AbstractMetaList { };
        
        //template< typename THead, typename TTail > TypeList;
        
        //template< typename TTypeList > TypeValueList;        

        ///////////
        // Logic //
        ///////////
        template< bool expression, typename True, typename False > struct If;
        
        template< bool b > struct LogicalNot : TrueType { };
        
        template < > struct LogicalNot< true > : FalseType { };
        
        template< bool B1, bool B2, bool B3 = true, bool B4 = true, bool B5 = true, bool B6 = true, bool B7 = true > struct LogicalAnd;
        
        template< bool B1, bool B2, bool B3 = false, bool B4 = false, bool B5 = false, bool B6 = false, bool B7 = false > struct LogicalOr;
        
        
        ///////////////////////////////////
        // Type Manipulation & Utilities //
        ///////////////////////////////////
        template< typename T, typename U > struct IsSame : FalseType { };
        template< typename T > struct IsSame< T, T > : TrueType { };
        
        template< typename T > struct IsClass;
        
        template< typename T > struct IsFundamentalType;
        
        template< typename T > struct IsReference;        
        
        template< typename T > struct IsPointer;
        
        template< typename T > struct IsArray;
        
        template< typename T > struct IsEnum;
                
        template< typename T > struct IsPolymorphic;
        
        template< typename T > struct AddConst;
        
        template< typename T > struct AddVolatile;
        
        template< typename T > struct AddConstVolatile;
        
        template< typename T > struct AddPointer;
        
        template< typename T > struct AddReference;
        
        template< typename T > struct RemoveConst;
        
        template< typename T > struct RemoveVolatile;
        
        template< typename T > struct RemoveConstVolatile;
        
        template< typename T > struct RemovePointer;
        
        template< typename T > struct RemoveReference;
        
        ///////////////
        // Utilities //
        ///////////////
        template< typename T > struct MetaSizeOf;
        
        template< typename T > struct AlignmentOf;   
    }
}


#define RS_METAFACILITIES_IMPLEMENTATION_INCLUDE_GUARD
#include "rs/MetaFacilities.ipp"
#undef RS_METAFACILITIES_IMPLEMENTATION_INCLUDE_GUARD

#endif // RS_META_METAFACILITIES_HPP
